using System;
using System.Collections.Generic;
using System.Text;

namespace Pixysoft
{
    public class StringComparer
    {
        static bool ignoreCase = true;
        /// <summary>
        /// Compute Levenshtein distance
        /// </summary>
        /// <param name="s">The s.</param>
        /// <param name="t">The t.</param>
        /// <returns></returns>
        public static double LDCompare(string strS, string strT)
        {
            int[,] matrix; // matrix

            int lengthOfS; // length of s
            int lengthOfY; // length of t

            // Step 1
            lengthOfS = strS.Length;
            lengthOfY = strT.Length;
            if (lengthOfS == 0)
                return lengthOfY;

            if (lengthOfY == 0)
                return lengthOfS;


            matrix = new int[lengthOfS + 1, lengthOfY + 1];

            // Step 2
            for (int i = 0; i <= lengthOfS; i++)
            {
                matrix[i, 0] = i;
            }

            for (int j = 0; j <= lengthOfY; j++)
            {
                matrix[0, j] = j;
            }

            // Step 3
            for (int i = 1; i <= lengthOfS; i++)
            {

                char s_i = strS[i - 1];

                // Step 4
                for (int j = 1; j <= lengthOfY; j++)
                {

                    int cost = -1; // cost

                    char t_j = strT[j - 1];

                    // Step 5
                    if (ignoreCase)
                    {
                        int abs_i_j = Math.Abs(s_i - t_j);
                        if (abs_i_j == 32 || abs_i_j == 0)
                        {
                            cost = 0;
                        }
                        else
                        {
                            cost = 1;
                        }
                    }
                    else
                        if (s_i == t_j)
                        {
                            cost = 0;
                        }
                        else
                        {
                            cost = 1;
                        }

                    // Step 6
                    matrix[i, j] = Minimum(matrix[i - 1, j] + 1, matrix[i, j - 1] + 1, matrix[i - 1, j - 1] + cost);

                }

            }

            // Step 7
            int maxLength = Math.Max(lengthOfS, lengthOfY);
            return (double)(maxLength - matrix[lengthOfS, lengthOfY]) / maxLength;

        }
        /// <summary>
        /// Minimums the specified a.
        /// </summary>
        /// <param name="a">A.</param>
        /// <param name="b">The b.</param>
        /// <param name="c">The c.</param>
        /// <returns></returns>
        private static int Minimum(int a, int b, int c)
        {
            int mi;

            mi = a;
            if (b < mi)
            {
                mi = b;
            }
            if (c < mi)
            {
                mi = c;
            }
            return mi;

        }
        /// <summary>
        /// Gets or sets a value indicating whether [ignore case].
        /// </summary>
        /// <value><c>true</c> if [ignore case]; otherwise, <c>false</c>.</value>
        public static bool IgnoreCase
        {
            get { return ignoreCase; }
            set { ignoreCase = value; }
        }
    }

}
